// lifetime 和 scopes不是一个概念， lifetime 是一个变量的有效范围，而 scope 是一个代码块的有效范围
// lifetime 是一个变量的有效范围，而 scope 是一个代码块的有效范围。
// 生命周期（Lifetime）是 Rust 编程语言的一个重要概念，它允许 Rust 程序员在编译时就避免一些常见的内存安全问题。
// 生命周期的主要作用是确保内存安全，并帮助 Rust 自动地管理内存。

// borrow checker 是一个 Rust 编译器的检查器，它检查代码是否满足所有变量的生命周期规则。
// 生命周期规则是：
// - 每个 borrow 都必须在有效的生命周期内
// - 生命周期不能比变量的生命周期短
// - 生命周期不能比函数的生命周期短
// - 生命周期不能比结构体的生命周期短
// - 生命周期不能比 trait 的生命周期短
// - 生命周期不能比 impl 的生命周期短
// - 生命周期不能比闭包的生命周期短
// - 生命周期不能比静态变量的生命周期短
// - 生命周期不能比 const 变量的生命周期短

// 生命周期注解（Lifetime Annotations）
// 生命周期注解是一种特殊的语法，它允许 Rust 编译器检查代码是否满足所有变量的生命周期规则。
// 生命周期注解的语法是：
// - &i32        // 引用
// - &'a i32     // 带有生命周期的引用
// - &'a mut i32 // 带有可变性的带有生命周期的引用
// - fn(i32) -> i32 // 函数
// - impl<'a> MyTrait for &'a i32 // 带有生命周期的 trait 实现
// - struct Foo<'a> { x: &'a i32 } // 带有生命周期的结构体  

// 生命周期注解的作用是：
// - 帮助 Rust 编译器检查代码是否满足所有变量的生命周期规则
// - 帮助 Rust 自动地管理内存

fn print_refs<'a, 'b>(x: &'a i32, y: &'b i32) {
    println!("x is {} and y is {}", x, y);
}

fn  failed_borrow<'a>() {
    let _x =12;
    // 'a 生命周期比 '_x' 生命周期长，所以不能借用 '_x'
    let _y:&'a i32 = &_x; // 错误：'_x' does not live long enough
}

fn main() {
    let (four, nine) = (4, 9);
    print_refs(&four, &nine);

    failed_borrow();
}